package uf;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;

/**
 * 并查集 树结构 plus版
 */
public class UF_Tree_Weighted {
    // 记录结点元素和该元素所的父结点
    private int[] elementAndGroup;
    // 存储每个根结点对应的树中元素的个数 !!!!
    private int[] size;
    // 记录并查集中数据的分组个数
    private int count;

    public UF_Tree_Weighted(int N) {
        //初始情况下，每个元素都在一个独立的分组中，所以，初始情况下，并查集中的数据默认分为N个组
        this.count = N;
        //初始化数组
        elementAndGroup = new int[N];
        size = new int[N];
        for (int i = 0; i < N; i++) {
            elementAndGroup[i] = i;
        }

        //把sz数组中所有的元素初始化为1，默认情况下，每个结点都是一个独立的树，每个树中只有一个元素
        Arrays.fill(size, 1);
    }

    public int count() {
        return count;
    }

    private int find(int p) {
        while (true) {
            if (p == elementAndGroup[p]) {
                return elementAndGroup[p];
            }
            p = elementAndGroup[p];
        }
    }

    public boolean connected(int p, int q) {
        return find(p) == find(q);
    }


    public void union(int p, int q) {
        int pRoot = find(p);
        int qRoot = find(q);

        if (pRoot == qRoot) {
            return;
        }

        if (size[pRoot] < size[qRoot]) {
            elementAndGroup[pRoot] = qRoot;
            size[qRoot] += size[pRoot];
        } else {
            elementAndGroup[qRoot] = pRoot;
            size[pRoot] += size[qRoot];
        }

        count--;

    }

    public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(
                new InputStreamReader(
                        UF_Tree_Weighted.class.getClassLoader().getResourceAsStream("traffic_project.txt")));
        int number = Integer.parseInt(reader.readLine());
        UF_Tree_Weighted uf = new UF_Tree_Weighted(number);
        int roadNumber = Integer.parseInt(reader.readLine());
        for (int i = 0; i < roadNumber; i++) {
            String line = reader.readLine();
            int p = Integer.parseInt(line.split(" ")[0]);
            int q = Integer.parseInt(line.split(" ")[1]);
            uf.union(p, q);
        }
        // 剩余分组
        int groupNumber = uf.count();
        System.out.println(groupNumber - 1);


    }
}
